//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.IO.Packaging;
using System.Windows.Media.Imaging;
using OpenLS.Core.Serialization;

namespace OpenLS.Vml
{
    class VmlImage
    {
        private string _extension;
        private readonly string _contentType;
        private byte[] _rawData;

        public VmlImage (byte [] data, string extension, string contentType)
        {
            this._rawData = data;
            this._extension = extension;
            _contentType = contentType;
        }
        public VmlImage(BitmapSource source)
        {
            this.Source = source;
        }

        public BitmapSource Source { get; set; }

        public static VmlImage Load(ReadContext c, string Rid)
        {
            var id = Rid;
            var relationship = c.Part.GetRelationship(id);
            var targetUri = PackUriHelper.ResolvePartUri(c.Part.Uri, relationship.TargetUri);
            var bitmapPart =
                c.Part.Package.GetPart(targetUri);
            string extension = System.IO.Path.GetExtension(targetUri.ToString());
            var stream = bitmapPart.GetStream();
            switch (extension)
            {
                case ".emf":
                case ".wmf":
                    {
                        stream.Position = 0;
                        byte[] rawData = new byte[stream.Length];
                        stream.Read(rawData, 0, rawData.Length);
                        return new VmlImage(rawData, extension, bitmapPart.ContentType);
                    }
                default:
                    {
                        stream.Position = 0;
                        byte[] rawData = new byte[stream.Length];
                        stream.Read(rawData, 0, rawData.Length);
                        stream.Position = 0;
                        var result = new VmlImage(rawData, extension, bitmapPart.ContentType);
                        try
                        {
                            result.Source = BitmapDecoder.Create(stream, BitmapCreateOptions.PreservePixelFormat,
                                                                 BitmapCacheOption.OnLoad).Frames[0];
                        }
                        catch (Exception)
                        {
                        }
                        return result;
                    }
            }

        }
        public void Write(WriteContext c, string namePrefix)
        {
            Write(c, namePrefix, "id");
        }
        public void Write(WriteContext c, string namePrefix, string id)
        {
            var backgroundE = c;
            if (Source == null)
            {
                WriteRaw(c, namePrefix, backgroundE, id);

                return;
            }
            {
                try
                {
                    BitmapEncoder encoder = null;
                    BitmapFrame f;
                    if (Source is BitmapFrame)
                    {
                        f = (BitmapFrame) Source;
                        if (f.Decoder != null)
                            encoder = BitmapEncoder.Create(f.Decoder.CodecInfo.ContainerFormat);
                    }
                    f = BitmapFrame.Create(Source);
                    if (encoder == null)
                        encoder = new JpegBitmapEncoder();
                    PackagePart backgroundPart;

                    string fullName = namePrefix + "{0}" + encoder.CodecInfo.FileExtensions.Split(',')[0];
                    string typeName = encoder.CodecInfo.MimeTypes.Split(',')[0];
                    PackageRelationship relationship = GetPart(c, namePrefix, out backgroundPart, fullName, typeName);

                    encoder.Frames.Add(f);
                    using (var dest = backgroundPart.GetStream())
                    {
                        encoder.Save(dest);
                    }
                    backgroundE.SetString(OfficeConstants.RelationshipNamespace + id, relationship.Id);
                }
                catch
                {
                    WriteRaw(c, namePrefix, backgroundE, id);

                }
            }
        }

        private void WriteRaw(WriteContext c, string namePrefix, WriteContext backgroundE, string id)
        {
            PackagePart backgroundPart;
            string fullName = "data{0}" + this._extension;
            PackageRelationship relationship = GetPart(c, namePrefix, out backgroundPart, fullName, _contentType);

            using (var dest = backgroundPart.GetStream())
            {
                dest.Write(_rawData, 0, _rawData.Length);
            }
            backgroundE.SetString(OfficeConstants.RelationshipNamespace + id,relationship.Id);
        }

        private PackageRelationship GetPart(WriteContext c, string namePrefix, out PackagePart backgroundPart, string fullName, string typeName)
        {
            Uri uu1 = c.GetAvailableUri(fullName);
            var relationship = c.Part.CreateRelationship(
                uu1, TargetMode.Internal, ImageRelationshipNamespace);
            var uu = PackUriHelper.ResolvePartUri(relationship.SourceUri, relationship.TargetUri);
            backgroundPart = c.Part.Package.CreatePart(uu, typeName);
            return relationship;
        }

        private const string ImageRelationshipNamespace =
    @"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";

    }
}